#include "Market.hpp"

namespace Market
{
    namespace
    {
        /**
         * @brief 从分价表变动域开始进行数据更新
         */
        void Instrument::update(uint8_t const *p, uint8_t const *const end)
        {
            FiledHeader *filed = (FiledHeader *)p;
            while (p < end)
            {
                if (0x1001 == filed->filed_id)
                { // 可以没有
                    // LOG("分价表\n");
                }

                p += sizeof(FiledHeader) + filed->filed_length;
            }

            while (p < end)
            {
                switch (filed->filed_id)
                {
                case 0x1002:
                    // LOG("成交概要\n");
                    break;
                case 0x1011:
                    // LOG("最高价域\n");
                    break;
                case 0x1012:
                    // LOG("最低价域\n");
                    break;
                case 0x1013:
                    // LOG("开盘价域\n");
                    break;
                case 0x1014:
                    // LOG("收盘价域\n");
                    break;
                case 0x1015:
                    // LOG("涨停板价域\n");
                    break;
                case 0x1016:
                    // LOG("跌停板价域\n");
                    break;
                case 0x1017:
                    // LOG("结算价域\n");
                    break;
                case 0x1018:
                    // LOG("虚实度域\n");
                    break;
                case 0x1019:
                    // LOG("买报单统计信息变动域\n");
                    break;
                case 0x101A:
                    // LOG("卖报单统计信息变动域\n");
                    break;
                default:
                    LOG("Unknown FiledID\n");
                    break;
                }

                p += filed->filed_length + sizeof(FiledHeader);
            }
        }

        void Instrument::cache(int32_t snapshot_no, uint8_t *data, size_t len)
        {
            m_cached_incremental_data[snapshot_no].insert(m_cached_incremental_data[snapshot_no].end(), data, data + len);
        }

        void Instrument::proceeCachedIncrementalData(int32_t snapshot_no)
        {
            m_current_snapshot_no = snapshot_no;
            for (auto &p : m_cached_incremental_data)
            {
                if (p.first <= snapshot_no)
                {
                    continue;
                }
                update(p.second.data(), p.second.data() + p.second.size());
            }
        }


    }

        void Market::parseMIRP_Incremental(MIRPHeader const *const mirp_header)
        {
            static std::vector<uint8_t> huanchongqu;
            uint8_t const *body = (uint8_t *)mirp_header + sizeof(MIRPHeader);
            uint8_t const *end = body + mirp_header->length;

            std::shared_ptr<Instrument> instrument;

            if (mirp_header->flag & 0x10)
            {
                // 不是最后一个消息
                huanchongqu.insert(huanchongqu.end(), body, body + mirp_header->length);
                return;
            }
            else
            {
                if (!huanchongqu.empty())
                {
                    huanchongqu.insert(huanchongqu.end(), body, body + mirp_header->length);
                    body = huanchongqu.data();
                    end = body + huanchongqu.size();
                }
            }

            uint8_t *p = (uint8_t *)body;
            FiledHeader *filed = (FiledHeader *)p;

            int32_t snapshot_no = -1;
            int32_t instrument_no = -1;

            if (0x0003 == filed->filed_id)
            {
                uint8_t *data = (uint8_t *)(filed + 1);
                VInt *instrument_no_vint = (VInt *)data;
                data += instrument_no_vint->size();
                VInt *snapshot_no_vint = (VInt *)data;

                instrument_no = instrument_no_vint->val();
                snapshot_no = snapshot_no_vint->val();
                // LOG("合约编号: %ld 当前合约增量行情的快照编号:%ld\n", instrument_no->val(), change_no->val());

                p += sizeof(FiledHeader) + filed->filed_length;
            }
            else
            {
                LOG("ERROR\n");
                goto failed;
            }

            {
                auto it = m_instruments.find(instrument_no);
                if (it == m_instruments.end())
                {
                    instrument = std::make_shared<Instrument>(instrument_no);
                    m_instruments[instrument_no] = instrument;
                    // 需要对其进行缓存
                    instrument->cache(instrument->m_current_snapshot_no, p, end - p);
                }
                else
                {
                    instrument = it->second;
                    instrument->update(p, end);
                }
            }

        failed:
            huanchongqu.clear();
            return;
        }

        void Market::parseMDQP_Snapshot(MDQPHeader const *const mdqp_header)
        {
            static std::vector<uint8_t> huanchongqu;
            uint8_t *body = (uint8_t *)mdqp_header + sizeof(MDQPHeader);
            uint8_t *end = body + mdqp_header->length;
            std::shared_ptr<TopicMarket> topic_market;

            if (mdqp_header->flag_high & 0x1)
            {
                // 不是最后一个报文
                huanchongqu.insert(huanchongqu.end(), body, body + mdqp_header->length);
                return;
            }
            else
            {
                if (!huanchongqu.empty())
                {
                    huanchongqu.insert(huanchongqu.end(), body, body + mdqp_header->length);
                    body = huanchongqu.data();
                    end = body + huanchongqu.size();
                }
            }

            uint8_t *data = body;
            FiledHeader *filed = (FiledHeader *)data;

            // 中心切换历史域
            while (0x0032 == filed->filed_id)
            {
                // 没有包含该消息，不处理了
                LOG("中心切换历史域\n");
                data += sizeof(FiledHeader) + filed->filed_length;
                filed = (FiledHeader *)data;
            }

            // 结算会话
            if (0x0031 == filed->filed_id)
            {
                SettlementSessionResponse *settlement_session_response = (SettlementSessionResponse *)(filed + 1);
                LOG("结算会话 traing_day=%s SettlementGroupID=%s SettlementID=%d\n",
                    settlement_session_response->trading_day,
                    settlement_session_response->settlement_gruop_id,
                    settlement_session_response->settlement_id);

                data += sizeof(FiledHeader) + filed->filed_length;
                filed = (FiledHeader *)data;
            }
            else
            {
                LOG("ERROR\n");
                goto failed;
            }

            // 快照标识
            if (0x1001 == filed->filed_id)
            {
                SnapshotResponse *snapshot_response = (SnapshotResponse *)(filed + 1);
                LOG("快照标识 SnapNo=%d TopicId=%d\n", snapshot_response->snap_no, snapshot_response->topic_id);

                auto it = m_topic_markets.find(snapshot_response->topic_id);
                if (it == m_topic_markets.end())
                {
                    topic_market = std::make_shared<TopicMarket>(
                        snapshot_response->topic_id,
                        snapshot_response->snap_no);
                    m_topic_markets[snapshot_response->topic_id] = topic_market;
                }
                else
                {
                    topic_market = it->second;
                }

                data += sizeof(FiledHeader) + filed->filed_length;
                filed = (FiledHeader *)data;
            }
            else
            {
                LOG("ERROR\n");
                goto failed;
            }

            // 主题属性
            if (0x1003 == filed->filed_id)
            {
                MarketAttributeResponse *market_attribute_response = (MarketAttributeResponse *)(filed + 1);
                LOG("主题属性 MarketDataDepth=%d CipherAlgorithm=%c\n",
                    market_attribute_response->market_data_depth,
                    market_attribute_response->cipher_algorithm);

                data += sizeof(FiledHeader) + filed->filed_length;
                filed = (FiledHeader *)data;
            }
            else
            {
                LOG("ERROR\n");
                goto failed;
            }

            // 快照时间
            if (0x1002 == filed->filed_id)
            {
                SnapshotTimeResponse *snapshot_time_response = (SnapshotTimeResponse *)(filed + 1);
                LOG("快照时间 SnapDate=%s SnapTime=%s SnapMillisec=%d\n",
                    snapshot_time_response->snap_date,
                    snapshot_time_response->snap_time,
                    snapshot_time_response->snap_millisec);

                data += sizeof(FiledHeader) + filed->filed_length;
                filed = (FiledHeader *)data;
            }
            else
            {
                LOG("ERROR\n");
                goto failed;
            }

            // 增量行情编号
            if (0x1004 == filed->filed_id)
            {
                IncrementalMarketDataPacketNoResponse *change_no = (IncrementalMarketDataPacketNoResponse *)(filed + 1);
                LOG("增量行情编号 ChangeNo=%d\n", change_no->packet_no);

                topic_market->m_packet_no = change_no->packet_no;

                data += sizeof(FiledHeader) + filed->filed_length;
                filed = (FiledHeader *)data;
            }
            else
            {
                LOG("ERROR\n");
                goto failed;
            }

            while (data < end)
            {
                std::shared_ptr<Instrument> instrument;

                // 合约信息
                if (0x0101 == filed->filed_id)
                {
                    InstrumentInfoResponse *instrument_info_response = (InstrumentInfoResponse *)(filed + 1);

                    auto it = m_instruments.find(instrument_info_response->instrument_no);
                    if (it == m_instruments.end())
                    {
                        instrument = std::make_shared<Instrument>(instrument_info_response->instrument_no,
                                                                  topic_market->m_packet_no);
                        m_instruments[instrument_info_response->instrument_no] = instrument;
                    }
                    else
                    {
                        instrument = it->second;
                        // 处理已缓存的增量行情数据
                        instrument->proceeCachedIncrementalData(topic_market->m_packet_no);
                    }

                    instrument->m_instrument_info = *instrument_info_response;

                    LOG("合约信息 instrument_no=%d 商品代码=%s "
                        "product_class=%c "
                        "strike_price=%lf\n",
                        instrument_info_response->instrument_no,
                        instrument_info_response->underlying_instr_id,
                        instrument_info_response->product_class,
                        instrument_info_response->strike_price.val());

                    data += sizeof(FiledHeader) + filed->filed_length;
                    filed = (FiledHeader *)data;
                }
                else
                {
                    LOG("ERROR\n");
                    goto failed;
                }

                // 成交行情
                if (0x0102 == filed->filed_id)
                {
                    InstrumentTradingInfoResponse *instrument_trading_info_response = (InstrumentTradingInfoResponse *)(filed + 1);
                    instrument->m_instrument_trading_info = *instrument_trading_info_response;
                    // LOG("成交行情 instrument_no=%d last_price=%lf volume=%d turnover=%lf\n",
                    //     instrument_trading_info_response->instrument_no,
                    //     instrument_trading_info_response->last_price.val(),
                    //     instrument_trading_info_response->volume,
                    //     instrument_trading_info_response->turnover.val());
                    data += sizeof(FiledHeader) + filed->filed_length;
                    filed = (FiledHeader *)data;
                }
                else
                {
                    LOG("ERROR\n");
                    goto failed;
                }

                while ((uint8_t *)filed < end && filed->filed_id == 0x0103)
                {
                    // 分价表
                    InstrumentPriceLevelResponse *instrument_price_level_response = (InstrumentPriceLevelResponse *)(filed + 1);
                    // LOG("分价表 instrument_no=%d direction=%c price=%lf volume=%d\n",
                    //     instrument_price_level_response->instrument_no,
                    //     instrument_price_level_response->direction,
                    //     instrument_price_level_response->price.val(),
                    //     instrument_price_level_response->volume);
                    data += sizeof(FiledHeader) + filed->filed_length;
                    filed = (FiledHeader *)data;
                }

                // 报单统计信息，可以没有
                if (0x0104 == filed->filed_id)
                {
                    data += sizeof(FiledHeader) + filed->filed_length;
                    filed = (FiledHeader *)data;
                }
            }

            goto success;

        failed:
            LOG("ERROR! filed_id=0x%04x\n", filed->filed_id);

        success:
            huanchongqu.clear();
            return;
        }


} // namespace Market
